Next | Prev | Up | Top | Contents | Index
Mapping and Unmapping Functions
The functions for mapping memory and registers are mmap(), drvmmap(), munmap(), and v_mapphys().
mmap - Mapping the Device
drvmmap - Mapping the Device
When a user-level program wants to map device memory into its address space, the user program opens the special file corresponding to the particular device and uses the mmap() system call. Your driver needs to call drvmmap() -- which you need to write -- when a mmap call maps into a user's address space. drvmmap is logically similar to a drvopen routine; make sure it does whatever work your device requires. (See Chapter 2, "Writing a Device Driver," and the mmap(D2) man page for more details.)
The section of a user-level program that maps device memory into its own addressing space could look like:
#include "fcntl.h"
#include "sys/mman.h"
fd = open(special_file, O_RDWR);
addr = mmap(0, len, PROT_READ|PROT_WRITE,
MAP_PRIVATE, fd, off);
After the kernel performs basic sanity checking on the system call arguments, if the file descriptor passed to the mmap(2) system call represents a special file, the kernel looks in your driver object module and calls that device mapping function.
Synopsis
drvmap(dev, vt, off, len, prot)
dev_t dev; /* device number*/
vhandl_t *vt; /* handle to caller's
/* virtual address space */
off_t off; /* offset into device */
int len; /* # of bytes to map */
int prot; /* protections */
Arguments
- dev
- Gives your drvmap() function the device major and minor numbers. Use the major and minor macros to extract this information from dev.
- vt
- Gives your drvmap function a pointer to the kernel-level data structure that describes the virtual space to which the device memory will be mapped. Your driver needs this pointer when calling certain kernel service functions.
Caution: Your driver must treat this pointer as an "opaque" handle and try not to set any of the member values directly. The specifics of this structure are likely to change from release to release. Your drvmap() function may change the member values of this structure indirectly, but only by calling kernel service functions.
- off
- This offset within device memory, at which mapping begins, gives your drvmap() function the kernel's virtual address for the device.
- len
- Gives your drvmap() function the length of the device memory to be mapped into the user's address space.
- prot
- Gives your drvmap() function the protections that the user program specified when it called mmap().
munmap - Unmapping the Device
To unmap a device, the user program calls the munmap(2) system call:
munmap (addr, len);
where addr is the device virtual address returned by the mmap(2) function and len is the length of the mapped area. After performing device-independent unmapping in the user's space, the munmap(2) system call calls your driver's drvunmap() function if it is defined as an entry in the device switch table.
Synopsis
drvunmap(dev, vt);
dev_t dev; /* device number */
vhandl_t *vt; /* handle to caller's virtual
address space */
The vt and dev parameters are the same as for drvmap(), above.
Note: If a driver provides a mapping function but does not provide an unmapping function, the munmap() system call returns the ENODEV error condition to the user. Therefore, it is a good idea for your driver to provide a dummy unmapping function even if your driver does not need to perform any action to unmap the device.
v_mapphys - Mapping Device Control Registers and On-board Memory
Your driver can allow the user to map device registers and local memory from the user's virtual space to physical memory if your driver's drvmap() function calls v_mapphys().
Synopsis
int v_mapphys(vt, addr, len);
vhandl_t *vt;
caddr_t addr;
int len;
Arguments
- vt
- Your drvmap() function must give this parameter the opaque handle to the user's virtual address space. (The internals of the structure for the opaque handle are likely to change from release to release.)
- addr
- Your drvmap() function must give this parameter the kernel virtual address by which the device is accessed. (See "VME Slave Addressing" in Appendix A.) The system takes this address from the user's call to mmap(2) and hands it to the off parameter of your drvmap() function.
- len
- Your drvmap() function must give this parameter the number of bytes to be mapped. The system takes this value from the user's call to mmap(2) and hands it to the len parameter of your drvmap() function.
If successful, v_mapphys() returns 0. If v_mapphys() fails, it sets errno and returns -1. After a successful call to v_mapphys(), the device's registers at addr are mapped into the user's address space as designated by vt. You do not need any special unmapping, so the drvunmap() function does not need actions specified within it.
Caution: Your driver must be very careful when it maps device registers to a user process. It must carefully check the range of addresses that the user requests and make sure that the request references only the requested device. Because protection is available only up to a page boundary, configure the addresses of I/O cards so that they do not overlap a page. If they are allowed to overlap, an application process may be able to access more than one device, possibly a system device (for example, a disk controller or Ethernet). This can cause system secuity problems or other problems that are hard to diagnose.
- mmap - Mapping the Device drvmmap - Mapping the Device
-
- munmap - Unmapping the Device
-
- v_mapphys - Mapping Device Control Registers and On-board Memory
-
Next | Prev | Up | Top | Contents | Index